package com.example.util;

import org.apache.commons.lang3.reflect.FieldUtils;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 反射工具类，提供获取泛型类型、设置字段值等反射操作
 */
public class ReflectionUtils {

    /**
     * 获取类的泛型父类的指定位置的泛型类型
     * @param clazz 当前类的Class对象
     * @param index 泛型参数的索引（从0开始）
     * @return 泛型类型的Class对象，若获取失败则返回null
     */
    public static Class<?> getGenericSuperclassType(Class<?> clazz, int index) {
        // 获取父类的泛型信息
        Type genericSuperclass = clazz.getGenericSuperclass();
        if (!(genericSuperclass instanceof ParameterizedType)) {
            // 如果父类不是参数化类型，继续向上查找
            return getGenericSuperclassType(clazz.getSuperclass(), index);
        }

        // 获取泛型参数数组
        Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();
        if (index < 0 || index >= actualTypeArguments.length) {
            throw new IndexOutOfBoundsException("泛型参数索引超出范围");
        }

        Type type = actualTypeArguments[index];
        if (type instanceof Class) {
            // 直接是Class类型（非泛型类型）
            return (Class<?>) type;
        } else if (type instanceof ParameterizedType) {
            // 处理参数化类型（如List<String>，返回List.class）
            return (Class<?>) ((ParameterizedType) type).getRawType();
        } else if (type instanceof TypeVariable) {
            // 处理类型变量（如T、E等，尝试获取其边界类型）
            Type[] bounds = ((TypeVariable<?>) type).getBounds();
            if (bounds.length > 0 && bounds[0] instanceof Class) {
                return (Class<?>) bounds[0];
            }
        }
        return null;
    }

    /**
     * 给对象的指定字段设置值（支持私有字段）
     * @param obj 目标对象
     * @param fieldName 字段名
     * @param value 要设置的值
     * @throws NoSuchFieldException 字段不存在时抛出
     * @throws IllegalAccessException 访问权限不足时抛出
     */
    public static void setFieldValue(Object obj, String fieldName, Object value)
            throws NoSuchFieldException, IllegalAccessException {
        if (obj == null || fieldName == null || fieldName.isEmpty()) {
            throw new IllegalArgumentException("对象或字段名不能为空");
        }

        // 从对象的类及其父类中查找字段
        Class<?> clazz = obj.getClass();
        Field field = findField(clazz, fieldName);
        if (field == null) {
            throw new NoSuchFieldException("在类 " + clazz.getName() + " 中未找到字段 " + fieldName);
        }

        // 设置字段可访问（突破私有修饰符限制）
        field.setAccessible(true);
        // 设置字段值
        field.set(obj, value);
    }

    /**
     * 获取对象指定字段的值（支持私有字段）
     * @param entity 目标对象
     * @param fieldName 字段名
     * @return 字段的值
     * @throws NoSuchFieldException 字段不存在时抛出
     * @throws IllegalAccessException 访问权限不足时抛出
     */
    // 获取实体类字段值（支持私有字段）
    public static Object getFieldValue(Object entity, String fieldName) {
        try {
            return FieldUtils.readField(entity, fieldName, true); //使用Apache Commons Lang3 工具库的成熟 API
        } catch (IllegalAccessException e) {
            throw new RuntimeException("获取字段值失败：" + fieldName, e);
        }
    }

    public static Object getFieldValue2(Object obj, String fieldName)
            throws NoSuchFieldException, IllegalAccessException {
        if (obj == null || fieldName == null || fieldName.isEmpty()) {
            throw new IllegalArgumentException("对象或字段名不能为空");
        }

        // 从对象的类及其父类中查找字段
        Class<?> clazz = obj.getClass();
        Field field = findField(clazz, fieldName);
        if (field == null) {
            throw new NoSuchFieldException("在类 " + clazz.getName() + " 中未找到字段 " + fieldName);
        }

        // 设置字段可访问（突破私有修饰符限制）
        field.setAccessible(true);
        // 获取字段值
        return field.get(obj);
    }

    /**
     * 从类及其父类中查找指定名称的字段
     * @param clazz 要查找的类
     * @param fieldName 字段名
     * @return 找到的字段，若未找到则返回null
     */
    private static Field findField(Class<?> clazz, String fieldName) {
        // 递归查找父类，直到Object类
        while (clazz != null && clazz != Object.class) {
            try {
                return clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                // 当前类未找到，继续查找父类
                clazz = clazz.getSuperclass();
            }
        }
        return null;
    }
}
